package com.atguigu.spzx.gateway.filter;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.spzx.model.entity.h5.UserInfo;
import com.atguigu.spzx.model.vo.common.Result;
import com.atguigu.spzx.model.vo.common.ResultCodeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName: AuthGlobalFilter
 * @Package: com.atguigu.spzx.gateway.filter
 * @Description 网关全局过滤器
 * @Author 孤妤
 * @Date: 2023/12/19 18:01
 */
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取request对象和response对象
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        // request获取请求地址
        String path = request.getURI().getPath();
        if (path.contains("auth")) {
            // 证明需要登陆,获取用户信息
            UserInfo userInfo = getUserInfo(request);
            // 为null表示没有登录, 响应208的状态码
            if (userInfo==null){
                return out(response,ResultCodeEnum.NO_AUTH);
            }
        }
        return chain.filter(exchange);
    }
    private Mono<Void> out(ServerHttpResponse response, ResultCodeEnum resultCodeEnum) {
        Result result = Result.build(null, resultCodeEnum);
        byte[] bits = JSONObject.toJSONString(result).getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = response.bufferFactory().wrap(bits);
        //指定编码，否则在浏览器中会中文乱码
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        return response.writeWith(Mono.just(buffer));
    }
    // 获取userInfo对象
    private UserInfo getUserInfo(ServerHttpRequest request) {
        // 获取请求头
        List<String> list = request.getHeaders().get("token");
        // 请求头不为空获取token
        if (!CollectionUtils.isEmpty(list)) {
            String token = list.get(0);
            // token不为空根据token获取redis中的对象
            if (StringUtils.hasLength(token)) {
                String userInfoStr = redisTemplate.opsForValue().get("user:login:" + token);
                if (StringUtils.hasLength(userInfoStr)){
                    redisTemplate.opsForValue().set("user:login:"+token,userInfoStr,2, TimeUnit.HOURS);
                    UserInfo userInfo = JSONObject.parseObject(userInfoStr, UserInfo.class);
                    return userInfo;
                }
            }
        }
        return null;
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
